from zope.interface import Interface
from zope.interface import implements
from zope.component import getMultiAdapter

from shema.archetype.interfaces import Ilinkbanner
from shema.archetype.interfaces import IBannerProvider

from plone.memoize.instance import memoize
from Acquisition import aq_inner
from Products.CMFCore.utils import getToolByName

from plone.app.portlets.portlets import base
from plone.portlets.interfaces import IPortletDataProvider

from zope import schema
from zope.formlib import form
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from shema.archetype import archetypeMessageFactory as __
from Products.CMFPlone import PloneMessageFactory as _

class IPortletBanner(IPortletDataProvider):
    """A portlet

    It inherits from IPortletDataProvider because for this portlet, the
    data that is being rendered and the portlet assignment itself are the
    same.
    """

    count = schema.Int(title=_(u'Number of items to display'),
                       description=_(u'How many items to list.'),
                       required=True,
                       default=5)

    state = schema.Tuple(title=_(u"Workflow state"),
                         description=_(u"Items in which workflow state to show."),
                         default=('published',),
                         required=True,
                         value_type=schema.Choice(
                             vocabulary="plone.app.vocabularies.WorkflowStates")
                         )


class Assignment(base.Assignment):
    """Portlet assignment.

    This is what is actually managed through the portlets UI and associated
    with columns.
    """

    implements(IPortletBanner)

    def __init__(self, count=5, state=('published',)):
        self.count = count
        self.state = state

    @property
    def title(self):
        """This property is used to give the title of the portlet in the
        "manage portlets" screen.
        """
        return "Portlet Banner"


class Renderer(base.Renderer):
    """Portlet renderer.

    This is registered in configure.zcml. The referenced page template is
    rendered, and the implicit variable 'view' will refer to an instance
    of this class. Other methods can be added and referenced in the template.
    """

    render = ViewPageTemplateFile('portletbanner.pt')

    @property
    def available(self):
        return len(self._data())
 
    def promotions(self):
        for brain in self._data():
            promotion = brain.getObject()
            banner_provider = IBannerProvider(promotion)
            yield dict(title=promotion.title,
                       url=promotion.remoteUrl,
                       abrirJanela=promotion.abrirJanela,
                       image_tag=banner_provider.tag)

    @memoize
    def _data(self):
        context = aq_inner(self.context)
        limit = self.data.count
        state = self.data.state
        query = dict(object_provides=Ilinkbanner.__identifier__)        
        catalog = getToolByName(context, 'portal_catalog')
        
        promotions = catalog(portal_type='link banner',
                       review_state=state,
                       sort_on='Date',
                       sort_order='reverse',
                       sort_limit=limit)[:limit]
                       
        return promotions

# NOTE: If this portlet does not have any configurable parameters, you can
# inherit from NullAddForm and remove the form_fields variable.

class AddForm(base.AddForm):
    """Portlet add form.

    This is registered in configure.zcml. The form_fields variable tells
    zope.formlib which fields to display. The create() method actually
    constructs the assignment that is being added.
    """
    form_fields = form.Fields(IPortletBanner)

    def create(self, data):
        return Assignment(count=data.get('count', 5), state=data.get('state', ('published',)))

# NOTE: IF this portlet does not have any configurable parameters, you can
# remove this class definition and delete the editview attribute from the
# <plone:portlet /> registration in configure.zcml

class EditForm(base.EditForm):
    """Portlet edit form.

    This is registered with configure.zcml. The form_fields variable tells
    zope.formlib which fields to display.
    """
    form_fields = form.Fields(IPortletBanner)
